#include "chatdialog.h"
#include "ui_chatdialog.h"
#include"../widget/chatframe.h"
#include"globalsignal.h"
#include"save.h"
#include"httpmgr.h"
#include <QStandardItemModel>
#include <tcpmgr.h>
#include <usermgr.h>
#include"crecordsdialog.h"

/*
实现了聊天记录查询，初步实现选中组建群聊界面

现在的bug：
1.离线消息拉取后无法直接显示
2.接收到消息后不会自动创建聊天列表
3.获取本地数据还是有问题

现在主要修改本地的消息显示和读取历史消息等问题
需要实现有新消息，自动创建消息列表
*/

ChatDialog::ChatDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::ChatDialog)
{
    ui->setupUi(this);
    ui->friendList->verticalScrollBar()->setSingleStep(10);
    ui->chatList->verticalScrollBar()->setSingleStep(20);
    ui->splitter->setSizes(QList<int>() << 1000 << 10);
    ui->splitter->setChildrenCollapsible(false);
    ui->widget_2->hide();

    connect(ui->chatList->verticalScrollBar(), &QScrollBar::valueChanged, this, &ChatDialog::slot_load_chat_record);
    connect(ui->friendList->verticalScrollBar(), &QScrollBar::valueChanged, this, &ChatDialog::slot_load_user);
    // connect(GlobalSignal::GetInstance().get(), &GlobalSignal::sig_add_friend, this, &ChatDialog::slot_add_friend);
    connect(TcpMgr::GetInstance().get(), &TcpMgr::sig_add_text_msg, this, &ChatDialog::slot_add_text_msg);
    connect(GlobalSignal::GetInstance().get(), &GlobalSignal::sig_add_offline_text_msg, this, &ChatDialog::slot_add_offline_text_msg);

    loadMoreUser();

    QJsonObject json_obj;
    json_obj["uid"] = UserMgr::GetInstance()->getUid();
    HttpMgr::GetInstance()->PostHttpReq(QUrl(GATE_URL+"/getOfflineMessage"),
                                        QJsonDocument(json_obj).toJson(), ReqId::ID_GET_OFFLINE_MSG,Modules::GLOBALMOD);

    Save::GetInstance()->ConnectSQLite();
    std::vector<QString> list;
    Save::GetInstance()->GetChatRoom(list);
    for (QString name : list){
        slot_add_friend(name);
    }
}

ChatDialog::~ChatDialog()
{
    qDebug("ChatDialog::~ChatDialog");
    delete ui;
}

void ChatDialog::loadMoreUser()
{
    for(int i = 0; i < 20; i++){
        // addChatFrame(UserMgr::GetInstance()->getName(), "gjasdjf健康噶昆仑山i请问金克拉分色机覅哦",
        //              UserType::Current_User, NewsType::text, false);
    }
}

void ChatDialog::keyPressEvent(QKeyEvent *event)
{
    if (event->modifiers() == Qt::AltModifier ){
        if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
            qDebug("回车");
            on_sendBtn_clicked();
        }
    }

    QWidget::keyPressEvent(event);
}

void ChatDialog::slot_load_user(int v)
{
    static int maxScrollValue = ui->friendList->verticalScrollBar()->maximum() - 10;
    if (maxScrollValue > v){
        return;
    }
    loadMoreUser();
    maxScrollValue = ui->friendList->verticalScrollBar()->maximum() - 10;
}

void ChatDialog::slot_load_chat_record(int v)
{
    if (v != 0) return;
    loadChatRecord();
}

void ChatDialog::loadChatRecord()
{
    //剩余多少为加载的聊天记录
    unsigned int& NotLoaded{_chatRoomMap[_receiverUser]->getNotLoaded()};
    if (NotLoaded == 0){
        return;
    }
    std::vector<Message> msgs(NotLoaded < 20 ? NotLoaded : 20);
    int minId = _chatRoomMap[_receiverUser]->getPioneer() == 0 ? INT_MAX : _chatRoomMap[_receiverUser]->getPioneer();
    int id = Save::GetInstance()->QueryChatRecords(_receiverUser, minId, msgs);
    if (id == 0){
        qDebug() << "获取聊天记录错误";
        return;
    }
    _chatRoomMap[_receiverUser]->setPioneer(id);
    NotLoaded -= msgs.size();

    QString me{UserMgr::GetInstance()->getName()};

    int max1 = ui->chatList->verticalScrollBar()->maximum();
    for (const Message& msg : msgs){
        if (msg._is_me){
            addChatFrame(me, msg._message, UserType::Current_User, NewsType::text, msg._time, true);
        }else{
            addChatFrame(_receiverUser, msg._message, UserType::Other_Users, NewsType::text, msg._time, true);
        }
    }
    ui->chatList->verticalScrollBar()->setValue(ui->chatList->verticalScrollBar()->maximum() - max1);
}

void ChatDialog::slot_add_friend(const QString &name)
{
    ChatUserWid *customWidget = new ChatUserWid(name, Save::GetInstance()->QueryChatSum(name));
    _chatRoomMap[name] = customWidget;
    connect(customWidget, &ChatUserWid::sig_switch_user, this, &ChatDialog::slot_switch_user);

    QString msg;
    customWidget->setTime(Save::GetInstance()->GetMaxRecord(name, msg));
    customWidget->setNews(msg);

    QListWidgetItem *item = new QListWidgetItem(ui->friendList);
    ui->friendList->setItemWidget(item, customWidget);
    item->setSizeHint(customWidget->sizeHint());
    ui->friendList->insertItem(_userNum++, item);
}

void ChatDialog::slot_add_group(const QString &name, const int num, const QString &uuid)
{
    qDebug() << name << uuid;

    ChatUserWid *customWidget = new ChatUserWid(name, Save::GetInstance()->QueryChatSum(name));
    _chatRoomMap[name] = customWidget;
    connect(customWidget, &ChatUserWid::sig_switch_user, this, &ChatDialog::slot_switch_user);

    QString msg;
    customWidget->setTime(Save::GetInstance()->GetMaxRecord(name, msg));
    customWidget->setNews(msg);

    QListWidgetItem *item = new QListWidgetItem(ui->friendList);
    ui->friendList->setItemWidget(item, customWidget);
    item->setSizeHint(customWidget->sizeHint());
    ui->friendList->insertItem(_userNum++, item);
}

void ChatDialog::slot_switch_user(const QString &name)
{
    if (clickedOnce){
        ui->widget_2->show();
        clickedOnce = false;
    }

    if (_receiverUser == name) return;
    if (!_receiverUser.isEmpty()){//恢复上一个用户的状态
        _chatRoomMap[_receiverUser]->setNotLoaded(Save::GetInstance()->QueryChatSum(_receiverUser));
        _chatRoomMap[_receiverUser]->setPioneer(0);
    }

    _receiverUser = name;
    _chatRoomMap[_receiverUser]->setNotLoaded(Save::GetInstance()->QueryChatSum(_receiverUser));
    ui->chatList->clear();

    loadChatRecord();
    ui->chatList->scrollToBottom();
    emit sig_switch_user(_receiverUser);
}

void ChatDialog::slot_contacts_switch_user(const QString &name)
{
    int count = ui->friendList->count();
    for (int i = 0; i < count; ++i) {
        ChatUserWid *customWidget = qobject_cast<ChatUserWid *>(ui->friendList->itemWidget(ui->friendList->item(i)));
        if (!customWidget) continue;
        if (customWidget->getName() == name){
            QListWidgetItem *item = ui->friendList->item(i);
            ui->friendList->setCurrentItem(item); // 设置当前选中项
            ui->friendList->scrollToItem(item, QListWidget::PositionAtCenter); // 确保项可见
            ui->friendList->setFocus(); // 确保 QListWidget 获得焦点
            customWidget->pitchOn();
            return;
        }
    }

    slot_add_friend(name);
}

//添加一行消息
void ChatDialog::addChatFrame(const QString &sender, const QString &text, const UserType &type, const NewsType &nt, const QDateTime& time, bool b)
{
    //如果项的父指针是QListWidget 就无法指定位置插入
    ChatFrame *f = new ChatFrame(sender, text, type, nt, ui->chatList);
    QListWidgetItem *item = new QListWidgetItem();

    connect(f, &ChatFrame::InterfaceUpdate, this, [item](const QSize& size){
        item->setSizeHint(size);
    });
    item->setSizeHint(f->sizeHint());

    if (b)ui->chatList->insertItem(0, item);
    else {
        ui->chatList->addItem(item);
        if (sender != UserMgr::GetInstance()->getName()){
            _chatRoomMap[sender]->setNews(text);
            _chatRoomMap[sender]->setTime(time);
        }else{
            _chatRoomMap[_receiverUser]->setNews(text);
            _chatRoomMap[_receiverUser]->setTime(time);
        }
    }
    ui->chatList->setItemWidget(item, f);
}

void ChatDialog::on_sendBtn_clicked()
{
    QString msg = ui->textEdit->toPlainText();
    if (msg.isEmpty()) return;
    QJsonObject jsonObj;
    jsonObj["token"] = UserMgr::GetInstance()->getToken();
    jsonObj["message"] = msg;
    jsonObj["receiver"] = _receiverUser;

    if (_chatRoomMap[_receiverUser]->isGroup()){
        jsonObj["receiver"] = _chatRoomMap[_receiverUser]->getUUID();
        QJsonDocument doc(jsonObj);
        emit TcpMgr::GetInstance()->sig_send_data(ReqId::ID_TEXT_CHAT_GROUP_MSG, doc.toJson(QJsonDocument::Compact));
    }else{
        QJsonDocument doc(jsonObj);
        emit TcpMgr::GetInstance()->sig_send_data(ReqId::ID_TEXT_CHAT_MSG, doc.toJson(QJsonDocument::Compact));
    }

    addChatFrame(UserMgr::GetInstance()->getName(), msg, UserType::Current_User, NewsType::text, QDateTime::currentDateTime(), false);
    ui->textEdit->clear();
    ui->chatList->scrollToBottom();

    // // 假设你已经有一个包含QWidget的QListWidgetItem，并且知道它的row位置
    // int rowIndex = 2; // 假设你要移动的是第三项
    // QListWidgetItem *item = ui->friendList->takeItem(rowIndex); // 移除该项
    // ChatUserWid *widget = qobject_cast<ChatUserWid*>(ui->friendList->itemWidget(item));
    // widget->setParent(nullptr);
    // ui->friendList->insertItem(0, item);
    // ui->friendList->setItemWidget(item, widget);
}

void ChatDialog::slot_add_text_msg(const QString &sender, const QString &msg)
{
    if (sender != _receiverUser) {
        if (!_chatRoomMap.contains(sender)){
            slot_add_friend(sender);
        }
        _chatRoomMap[sender]->addOne();
        _chatRoomMap[sender]->setNews(msg);
        _chatRoomMap[sender]->setTime(QDateTime::currentDateTime());
        return;
    }
    addChatFrame(sender, msg, UserType::Other_Users, NewsType::text, QDateTime::currentDateTime(), false);
}

void ChatDialog::slot_add_offline_text_msg(const QString &sender, const QString &msg, const QDateTime &time)
{
    if (sender != _receiverUser) {
        if (!_chatRoomMap.contains(sender)){
            slot_add_friend(sender);
        }
        _chatRoomMap[sender]->addOne();
        _chatRoomMap[sender]->setNews(msg);
        _chatRoomMap[sender]->setTime(QDateTime::currentDateTime());
        return;
        return;
    }
    addChatFrame(sender, msg, UserType::Other_Users, NewsType::text, time, false);
}

void ChatDialog::on_pushButton_3_clicked()
{
    CRecordsDialog *c = new CRecordsDialog(_receiverUser);
    c->setWindowTitle("与" + _receiverUser + "的聊天记录");
    c->setAttribute(Qt::WA_DeleteOnClose);
    c->show();
}
